using System;
using System.Collections;
using System.Collections.Generic;
using System.Data.Objects.DataClasses;
using System.Linq;
using System.Reflection;
using System.Text;
using EntityFramework.ServiceLayer;

namespace Source.Tests.Utility
{
    public class TestEntityFactory
    {
        private readonly IActiveObjectContextManager activeObjectContextManager;

        public TestEntityFactory(IActiveObjectContextManager activeObjectContextManager)
        {
            this.activeObjectContextManager = activeObjectContextManager;
        }

        private GenericRepository genericRepository;
        public Projects CreatePersistedProjects()
        {
            return Persist(CreateUnpersitedProjects());
        }
        public Projects CreateUnpersitedProjects()
        {
            return new Projects()
                       {
                           CreatedTime = DateTime.Now,
                           ProjectName = "test",
                           BidingEnds = DateTime.Now.AddDays(1),
                           UserName = "testName",
                           Status = "Open",
                           Options = 3,
                           BuggetRange = "400",
                           SelectProvider = "whoamI"

                       };
        }

        private GenericRepository GenericRepository
        {
            get
            {
                if (genericRepository == null) genericRepository = new GenericRepository(activeObjectContextManager);
                return genericRepository;
            }
        }

        private IObjectContext ObjectContext
        {
            get
            {
                return activeObjectContextManager.GetActiveObjectContext();
            }
        }

        public TEntity Persist<TEntity>(TEntity entity) where TEntity : IEntity
        {
            ObjectContext.AddObjectOrAttach(entity);
            ObjectContext.SaveChanges();
            ObjectContext.Clear();

            return entity;
        }

        public void Delete<TEntity>(object id) where TEntity : EntityObject, IEntity
        {
            var entity = new GenericRepository(activeObjectContextManager).Get<TEntity>(id);
            Delete(entity);
        }

        public void Delete<TEntity>(TEntity entity) where TEntity : IEntity
        {
            ObjectContext.DeleteObject(entity);
            ObjectContext.SaveChanges();
            ObjectContext.Clear();
        }

        public TEntity Get<TEntity, TId>(TId id)
            where TEntity : EntityObject, IEntity<TId>
        {
            var entityKey = ObjectContext.CreateEntityKey<TEntity, TId>(id);
            var entity = (TEntity)ObjectContext.GetObjectByKey(entityKey);

            ObjectContext.Detach(entity);

            return entity;
        }

        private static readonly Random random = new Random(DateTime.Now.Millisecond);
        public string GenerateRandomString(int length)
        {
            // quick fix for VarChar(max) fields that have a length of -1
            if (length < 0) { length = 20; }

            string alfabet = "abcdefghijklmnopqrstuvwxyz";

            StringBuilder randomString = new StringBuilder();

            for (int i = 0; i < length; i++)
            {
                randomString.Append(alfabet.ToCharArray()[random.Next(alfabet.Length)]);
            }

            return randomString.ToString();
        }
    }
}
